﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MySql.Data.MySqlClient;
using DateBaseConnectionPool;

namespace TestMySqlConnetPoll
{
    public class ObjDcdlType
    {
        public int devNo = -1;
        public Int32 u_time = 0;
        public byte zh_order = 0;
        public Int16 dotNumber = 0;
        public List<ObjRCurValue> qxA = new List<ObjRCurValue>();
        public List<ObjRCurValue> qxB = new List<ObjRCurValue>();
        public List<ObjRCurValue> qxC = new List<ObjRCurValue>();
        public List<ObjRCurValue> glqx = new List<ObjRCurValue>();
    }

    public struct ObjRCurValue
    {
        public Int16 wValue;
        public ObjValue tValue;        
    }

    public class DcdlqxTable
    {
        #region 外部函数接口，道岔动作电流,产考，摩擦曲线 外部变量定义

        /// <summary>
        /// 以设备号做键值
        /// </summary>

//        public objCodeDev DcdlqxTimeDevNo = new objCodeDev();  //道岔电流曲线时间列表对应的设备号
        public List<DateTime> DcdlqxTimeList = new List<DateTime>();    //换设备时首先需要调用时间列表
        
        public int dlqxErrorFlag = 0;
        public bool Ready_DcdlqxTime = false;       //道岔电流曲线的时间列表准备好。
        public bool Ready_DcdlqxValue = false;      //道岔动作电流曲线准备好。

        private int  DcdlqxDevNo = -1;           //道岔电流曲线值对象的设备号
        //public ObjDcdlType DcdlqxValueList = new ObjDcdlType();     //道岔动作电流曲线, 只保存一条的值，重新查询都清除该值
        public Dictionary<DateTime, ObjDcdlType> DcdlqxValueList = new Dictionary<DateTime, ObjDcdlType>();

        public int ckqxErrorFlag = 0;
        public int DcdzCKqxDevNo = -1;
        public List<ObjDcdlType> DcdzCKqxValueList = new List<ObjDcdlType>(); //道岔动作参考曲线,一次把所有的参考曲线都读出来，一般有两条，定位到反位，反位到定位

        public int mcqxErrorFlag = 0;
        public int DcdzMcqxDevNo = -1;
        public List<ObjDcdlType> DcdzMcqxValueList = new List<ObjDcdlType>(); //道岔动作摩擦曲线


        public bool Ready_DcdzCKValue = false;      //道岔动作参考曲线准备好
        public bool Ready_DcdzMcValue = false;      //导致动作摩擦曲线准备好

        private Mutex keyMutex = new Mutex();
        static private int keykey = 0;
        public struct DcdlqxThreadStruct
        {
            public int qxtype;  //曲线类型，参考，或者摩擦
            public string TableName;
            public int codetype;    //非模拟量类型，为曲线类型
            public int dev_no;
            public int u_time;
            public bool qxA;
            public bool qxB;
            public bool qxC;
            public bool glqx;
        }

//        public void Read_DcdlqxTimeList(AnalogCodeType codetype, Int16 dev_no)
        public void Read_DcdlqxTimeList(string DevName)
        {
            Ready_DcdlqxTime = false;
            dlqxErrorFlag = 0;
            DcdlqxTimeList.Clear();
            string TableName = "dcdlqx";
            DcdlqxThreadStruct obj = new DcdlqxThreadStruct();
            //obj.codetype = 0x10;
            obj.codetype = 0x01;
            obj.dev_no = c_Device.GetDcdlqxDevNo(DevName);
            obj.TableName = TableName;
            if (obj.dev_no >= 0) ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadDcdlqxTimeList), obj);
            else
            {
                dlqxErrorFlag = 1;
            }
        }

//        public void Read_DcdlqxValueList(int u_time, AnalogCodeType codetype, short dev_no, bool qxA, bool qxB, bool qxC, bool glqx)
        public void Read_DcdlqxValueList(DateTime time ,string DevName)
        {
            Ready_DcdlqxValue = false;
            dlqxErrorFlag = 0;
            string TableName = "dcdlqx";
            DcdlqxThreadStruct obj = new DcdlqxThreadStruct();
            obj.TableName = TableName;
            obj.u_time =(int) MySql.DateTimeToTime_t(time);
            //obj.codetype = 0x10;
            obj.codetype = 0x01;
            obj.dev_no = c_Device.GetDcdlqxDevNo(DevName);

            if (DcdlqxDevNo == obj.dev_no && DcdlqxValueList.Keys.Contains(time)) //在缓冲区内
            {
                Ready_DcdlqxValue = true;
                return;
            }
            if (DcdlqxDevNo != obj.dev_no)  //换设备清除列表
            {
                DcdlqxDevNo = obj.dev_no;
                DcdlqxValueList.Clear();
            }

            if (obj.dev_no >= 0)
            {
                int flag = c_Device.DcdlqxDevList[obj.dev_no].Flag;
                obj.qxA = true;
                if (c_Device.GetDctype(obj.dev_no) == 0)
                {
                    obj.qxB = false;
                    obj.qxC = false;
                    obj.glqx = false;
                }
                else if (c_Device.GetDctype(obj.dev_no) == 1)
                {
                    obj.qxB = true;
                    obj.qxC = true;
                    obj.glqx = true;
                }
                else
                {
                    dlqxErrorFlag = 1;
                    return;
                }
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadDcdlqxCurveData), obj);
            }
            else dlqxErrorFlag = 1;
        }

//        public void Read_DcCkValueList(AnalogCodeType codetype, short dev_no, bool qxA, bool qxB, bool qxC, bool glqx)
        public void Read_DcCkValueList(string DevName)
        {
            Ready_DcdzCKValue = false;
            ckqxErrorFlag = 0;
            DcdlqxThreadStruct obj = new DcdlqxThreadStruct();
            string TableName = "dcdlck$mcqx";
            obj.TableName = TableName;
            obj.qxtype = 1;     //参考曲线
            obj.codetype = 0x10;
            obj.dev_no = c_Device.GetDcdlqxDevNo(DevName);

            if (DcdzCKqxDevNo == obj.dev_no)
            {
                Ready_DcdzCKValue = true;
                return;
            }
            else
            {
                DcdzCKqxDevNo = obj.dev_no;
                DcdzCKqxValueList.Clear();
            }

            obj.qxA = true;
            if (obj.dev_no >= 0)
            {
                obj.qxA = true;
                if (c_Device.GetDctype(obj.dev_no) == 0)
                {
                    obj.qxB = false;
                    obj.qxC = false;
                    obj.glqx = false;
                }
                else if (c_Device.GetDctype(obj.dev_no) == 1)
                {
                    obj.qxB = true;
                    obj.qxC = true;
                    obj.glqx = true;
                }
                else
                {
                    ckqxErrorFlag = 1;
                    return;
                }
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadDcCkMcQX), obj);
            }
            else ckqxErrorFlag = 1;
        }

//        public void Read_DcMCValueList(AnalogCodeType codetype, short dev_no, bool qxA, bool qxB, bool qxC, bool glqx)
        public void Read_DcMCValueList(string DevName)
        {
            Ready_DcdzMcValue = false;            
            mcqxErrorFlag = 0;
            DcdlqxThreadStruct obj = new DcdlqxThreadStruct();
            string TableName = "dcdlck$mcqx";
            obj.TableName = TableName;
            obj.qxtype = 2;     //摩擦曲线
            obj.codetype = 0x10;
            obj.dev_no = c_Device.GetDcdlqxDevNo(DevName);
            if (obj.dev_no >= 0)
            {
                obj.qxA = true;
                if (c_Device.GetDctype(obj.dev_no) == 0)
                {
                    obj.qxB = false;
                    obj.qxC = false;
                    obj.glqx = false;
                }
                else if (c_Device.GetDctype(obj.dev_no) == 1)
                {
                    obj.qxB = true;
                    obj.qxC = true;
                    obj.glqx = true;
                }
                else
                {
                    mcqxErrorFlag = 1;
                    return;
                }
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadDcCkMcQX), obj);
            }
            else mcqxErrorFlag = 1;
        }

        #region   道岔电流、功率曲线的插入，读取操作函数
        /// <summary>
        /// 写道岔动作电流曲线表,只有一条曲线，或者三条曲线都有，或者三条曲线加功率曲线都有时调用该函数
        /// 曲线都有时，需要一次性插入
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="zh_order"></param>
        /// <param name="dotNumber"></param>
        /// <param name="qxA"></param>
        /// <param name="qxB"></param>
        /// <param name="qxC"></param>
        /// <param name="glqx"></param>
        /// <returns></returns>
        private bool InsertDcdlqxTable(string TableName, int u_time, AnalogCodeType codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA, byte[] qxB = null, byte[] qxC = null, byte[] glqx = null)
        {
            bool tmpFlag = false;
            if (TableName == "") return tmpFlag;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();

                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                        
                
                if (con != null)
                {
                    StringBuilder InsertStatement = new StringBuilder();

                    InsertStatement.Append(string.Format("insert into {0} (u_time,codetype,dev_no,zh_order,dotNumber,qxA", TableName));

                    if (qxB != null) InsertStatement.Append(",qxB");
                    if (qxC != null) InsertStatement.Append(",qxC");
                    if (glqx != null) InsertStatement.Append(",gl");
                    InsertStatement.Append(")");
                    InsertStatement.Append("values(?u_time,?codetype,?dev_no,?zh_order,?dotNumber,?qxA");
                    if (qxB != null) InsertStatement.Append(",?qxB");
                    if (qxC != null) InsertStatement.Append(",?qxC");
                    if (glqx != null) InsertStatement.Append(",?gl");
                    InsertStatement.Append(")");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);

                    InsertCommand.Parameters.Add(new MySqlParameter("?u_time", MySqlDbType.UInt32)).Value = u_time;
                    InsertCommand.Parameters.Add(new MySqlParameter("?codetype", MySqlDbType.Byte)).Value = codetype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.UInt16)).Value = dev_no;
                    InsertCommand.Parameters.Add(new MySqlParameter("?zh_order", MySqlDbType.UByte)).Value = zh_order;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumber", MySqlDbType.UInt16)).Value = dotNumber;
                    InsertCommand.Parameters.Add(new MySqlParameter("?qxA", MySqlDbType.VarBinary)).Value = qxA.ToArray();
                    if (qxB != null)
                        InsertCommand.Parameters.Add(new MySqlParameter("?qxB", MySqlDbType.VarBinary)).Value = qxB.ToArray();
                    if (qxC != null)
                        InsertCommand.Parameters.Add(new MySqlParameter("?qxC", MySqlDbType.VarBinary)).Value = qxC.ToArray();
                    if (glqx != null)
                        InsertCommand.Parameters.Add(new MySqlParameter("?gl", MySqlDbType.VarBinary)).Value = glqx.ToArray();

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }

        /// <summary>
        /// 只有一条曲线和功率曲线时的插入方法
        /// </summary>
        /// <param name="f"></param>无用，用户区分重装函数
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="zh_order"></param>
        /// <param name="dotNumber"></param>
        /// <param name="qxA"></param>动作曲线，只有一条曲线时，都存在A相曲线内
        /// <param name="glqx"></param>功率曲线
        /// <returns></returns>
        private bool InsertDcdlqxTable(bool f, string TableName, int u_time, AnalogCodeType codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA, byte[] glqx)
        {
            bool tmpFlag = false;
            if (TableName == "") return tmpFlag;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                
                if (con != null)
                {
                    StringBuilder InsertStatement = new StringBuilder();

                    InsertStatement.Append(string.Format("insert into {0}(u_time,codetype,dev_no,zh_order,dotNumber,qxA,gl)", TableName));

                    InsertStatement.Append("values(?u_time,?codetype,?dev_no,?zh_order,?dotNumber,?qxA,?gl)");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);

                    InsertCommand.Parameters.Add(new MySqlParameter("?u_time", MySqlDbType.UInt32)).Value = u_time;
                    InsertCommand.Parameters.Add(new MySqlParameter("?codetype", MySqlDbType.Byte)).Value = codetype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.UInt16)).Value = dev_no;
                    InsertCommand.Parameters.Add(new MySqlParameter("?zh_order", MySqlDbType.UByte)).Value = zh_order;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumber", MySqlDbType.UInt16)).Value = dotNumber;
                    InsertCommand.Parameters.Add(new MySqlParameter("?qxA", MySqlDbType.VarBinary)).Value = qxA.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?gl", MySqlDbType.VarBinary)).Value = glqx.ToArray();

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }

        private void AddToDcdlqxTimeList(int u_time, short dev_no)
        {
            DateTime t = new DateTime();
            t = MySql.Time_tToDateTime(u_time);            
            if (DcdlqxTimeList.Contains(t)) { }
            else DcdlqxTimeList.Add(t);
        }

        /// <summary>
        /// 按照某个设备，取该设备道岔动作电流的时间列表
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="dev_no"></param>
        /// <returns></returns>
        private void ThreadReadDcdlqxTimeList(object o)
        {
            DcdlqxThreadStruct obj = new DcdlqxThreadStruct();
            obj = (DcdlqxThreadStruct)o;

            string TableName = obj.TableName;
            int  codetype = obj.codetype;
            Int16 dev_no = (Int16)obj.dev_no;
            if (TableName == "") return;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    dlqxErrorFlag = 2;
                }
                
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append(string.Format("select u_time from {0} where dev_no = {1} and codetype = {2}", TableName, dev_no, codetype));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            int u_time = read.GetInt32(0);
                            AddToDcdlqxTimeList(u_time, dev_no);
                        }
                        read.Close();
                        Ready_DcdlqxTime = true;    //读取成功
                    }
                    catch (MySqlException e)
                    {
                        dlqxErrorFlag = 3;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        dlqxErrorFlag = 4;
                    }
                }
                else dlqxErrorFlag = 6;
            }
            else dlqxErrorFlag = 7;
        }

        private void AddDataToDcdlqxValue(int u_time, int codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA = null, byte[] qxB = null, byte[] qxC = null, byte[] glqx = null)
        {
            ObjDcdlType tmp = new ObjDcdlType();
            tmp.devNo = dev_no;
            tmp.u_time = u_time;
            tmp.zh_order = zh_order;
            tmp.dotNumber = dotNumber;

            string AnalogName = "道岔动作电流曲线";
            if (qxA != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {
                    int TmpValue = qxA[m] + (qxA[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.qxA.Add(v);
                }
            }
            if (qxB != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {
                    int TmpValue = qxB[m] + (qxB[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.qxB.Add(v);
                }
            }
            if (qxC != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {
                    int TmpValue = qxC[m] + (qxC[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.qxC.Add(v);
                }
            }
            if (glqx != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {
                    int TmpValue = glqx[m] + (glqx[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.glqx.Add(v);
                }
            }
            DateTime d_time = MySql.Time_tToDateTime(u_time);
            DcdlqxValueList.Add(d_time, tmp);
        }

        private void AddDataToDcdlqxValue(bool f, int u_time, int codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA, byte[] glqx)
        {
            ObjDcdlType tmp = new ObjDcdlType();
            tmp.devNo = dev_no;
            tmp.u_time = u_time;
            tmp.zh_order = zh_order;
            tmp.dotNumber = dotNumber;
            string AnalogName =  "道岔动作电流曲线";
            int m = 0;
            for (int i = 0; i < dotNumber; i++)
            {
                int TmpValue = qxA[m] + (qxA[m + 1] << 8);
                m += 2;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                ObjRCurValue v = new ObjRCurValue();
                v.wValue = (short)TmpValue;
                v.tValue = t;
                tmp.qxA.Add(v);
            }
            m = 0;
            for (int i = 0; i < dotNumber; i++)
            {
                int TmpValue = glqx[m] + (glqx[m + 1] << 8);
                m += 2;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                ObjRCurValue v = new ObjRCurValue();
                v.wValue = (short)TmpValue;
                v.tValue = t;
                tmp.glqx.Add(v);
            }
            DateTime d_time = MySql.Time_tToDateTime(u_time);
            DcdlqxValueList.Add(d_time,tmp);
        }

        /// <summary>
        /// 读取某个转辙机某一时刻的所有曲线，必须把该转辙机所有的曲线一次读出来，放在缓冲区内，包括功率曲线
        /// 换设备后，清空缓冲区
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="qxA"></param>
        /// <param name="qxB"></param>
        /// <param name="qxC"></param>
        /// <param name="glqx"></param>
        /// <returns></returns>
        private void ThreadReadDcdlqxCurveData(object o)
        {
            DcdlqxThreadStruct obj = new DcdlqxThreadStruct();
            obj = (DcdlqxThreadStruct)o;
            string TableName = obj.TableName;
            int u_time = obj.u_time;
            int codetype = obj.codetype;
            short dev_no = (Int16)obj.dev_no;
            bool qxA = obj.qxA;
            bool qxB = obj.qxB;
            bool qxC = obj.qxC;
            bool glqx = obj.glqx;

            if (TableName == "") return;

            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    dlqxErrorFlag = 2;
                }
                        
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append("select zh_order,dotNumber");
                    if (qxA == true) SelectStatement.Append(",qxA");
                    if (qxB == true) SelectStatement.Append(",qxB");
                    if (qxC == true) SelectStatement.Append(",qxC");
                    if (glqx == true) SelectStatement.Append(",gl");

                    SelectStatement.Append(string.Format(" from {0} where u_time = {1} and dev_no = {2}", TableName, u_time, dev_no));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            byte zh_order = read.GetByte(0);
                            Int16 dotNumber = read.GetInt16(1);
                            byte[] tqxa = new byte[dotNumber*2];
                            byte[] tqxb = new byte[dotNumber*2];
                            byte[] tqxc = new byte[dotNumber*2];
                            byte[] tglqx = new byte[dotNumber*2];
                            if (qxA)
                            {
                                read.GetBytes(read.GetOrdinal("qxA"), 0, tqxa, 0, dotNumber * 2);
                            }
                            if (qxB)
                            {
                                read.GetBytes(read.GetOrdinal("qxB"), 0, tqxb, 0, dotNumber * 2);
                            }
                            if (qxC)
                            {
                                read.GetBytes(read.GetOrdinal("qxC"), 0, tqxc, 0, dotNumber * 2);
                            }
                            if (glqx)
                            {
                                read.GetBytes(read.GetOrdinal("gl"), 0, tglqx, 0, dotNumber * 2);
                            }

                            if (qxA && (!qxB) && (!qxC) && (!glqx)) //只有一条曲线
                            {
                                AddDataToDcdlqxValue(u_time, codetype, dev_no, zh_order, dotNumber, tqxa);
                            }
                            else if (qxA && (!qxB) && (!qxC) && glqx)//有一条曲线和功率曲线
                            {
                                AddDataToDcdlqxValue(true, u_time, codetype, dev_no, zh_order, dotNumber, tqxa, tglqx);
                            }
                            else if (qxA && qxB && qxC && (!glqx))  //有三条曲线
                            {
                                AddDataToDcdlqxValue(u_time, codetype, dev_no, zh_order, dotNumber, tqxa, tqxb, tqxc);
                            }
                            else if (qxA && qxB && qxC && glqx)     //有四条曲线
                            {
                                AddDataToDcdlqxValue(u_time, codetype, dev_no, zh_order, dotNumber, tqxa, tqxb, tqxc, tglqx);
                            }
                        }
                        read.Close();
                        Ready_DcdlqxValue = true;
                    }
                    catch (MySqlException e)
                    {
                        dlqxErrorFlag = 4;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        dlqxErrorFlag = 5;
                    }
                }
                else dlqxErrorFlag = 6;
            }
            else dlqxErrorFlag = 7;
        }
        #endregion

        #region   道岔参考，摩擦曲线的插入，读取操作函数
        /// <summary>
        /// 写道岔参考，摩擦曲线表,只有一条曲线，或者三条曲线都有，或者三条曲线加功率曲线都有时调用该函数
        /// 曲线都有时，要一次性插入
        /// 首先删除数据库内相同设备，相同转换方向的参考，摩擦曲线再插入。
        /// </summary>
        /// <param name="qxtype"></param> 曲线类型，1=参考曲线，2=摩擦曲线
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="zh_order"></param>
        /// <param name="dotNumber"></param>
        /// <param name="qxA"></param>
        /// <param name="qxB"></param>
        /// <param name="qxC"></param>
        /// <param name="glqx"></param>
        /// <returns></returns>
        //public bool InsertDcCkMcQxTable(byte qxtype,  int u_time, AnalogCodeType codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA, byte[] qxB = null, byte[] qxC = null, byte[] glqx = null)
        public bool InsertDcCkMcQxTable(byte qxtype, ObjDcdlType obj)
        {
            bool tmpFlag = false;
            string TableName = "dcdlck$mcqx";
            if (TableName == "") return tmpFlag;
            int codetype = 0x10;    //道岔电流曲线类型
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                        
                if (con != null)
                {
                    //首先要把数据库内的曲线读出来，如果有相同的，需要首先删除，再插入

                    StringBuilder DeleteStatement = new StringBuilder();
                    DeleteStatement.Append(string.Format("delete from {0} where dev_no={1} and zh_order={2} and type={3} and codetype = {4}", TableName, obj.devNo, obj.zh_order, qxtype, codetype));
                    MySqlCommand delCommand = new MySqlCommand(DeleteStatement.ToString(), con);
                    delCommand.ExecuteNonQuery();


                    StringBuilder InsertStatement = new StringBuilder();

                    InsertStatement.Append(string.Format("insert into {0} (u_time,dev_no,codetype,type,zh_order,dotNumber,qxA", TableName));

                    if (obj.qxB != null) InsertStatement.Append(",qxB");
                    if (obj.qxC != null) InsertStatement.Append(",qxC");
                    if (obj.glqx != null) InsertStatement.Append(",gl");
                    InsertStatement.Append(")");
                    InsertStatement.Append("values(?u_time,?dev_no,?codetype,?type,?zh_order,?dotNumber,?qxA");
                    if (obj.qxB != null) InsertStatement.Append(",?qxB");
                    if (obj.qxC != null) InsertStatement.Append(",?qxC");
                    if (obj.glqx != null) InsertStatement.Append(",?gl");
                    InsertStatement.Append(")");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);

                    InsertCommand.Parameters.Add(new MySqlParameter("?u_time", MySqlDbType.UInt32)).Value = obj.u_time;
                    InsertCommand.Parameters.Add(new MySqlParameter("?codetype", MySqlDbType.Byte)).Value = codetype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.UInt16)).Value = obj.devNo;
                    InsertCommand.Parameters.Add(new MySqlParameter("?type", MySqlDbType.Byte)).Value = qxtype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?zh_order", MySqlDbType.UByte)).Value = obj.zh_order;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumber", MySqlDbType.UInt16)).Value = obj.dotNumber;
                    List<byte> tmpA = new List<byte>();
                    for (int i = 0; i < obj.qxA.Count; i++)
                    {
                        int v = obj.qxA[i].wValue;
                        tmpA.Add((byte)v);
                        tmpA.Add((byte)(v >> 8));
                    }
                    InsertCommand.Parameters.Add(new MySqlParameter("?qxA", MySqlDbType.VarBinary)).Value = tmpA.ToArray();
                    if (obj.qxB != null)
                    {
                        List<byte> tmpB = new List<byte>();
                        for (int i = 0; i < obj.qxB.Count; i++)
                        {
                            int v = obj.qxB[i].wValue;
                            tmpB.Add((byte)v);
                            tmpB.Add((byte)(v >> 8));
                        }
                        InsertCommand.Parameters.Add(new MySqlParameter("?qxB", MySqlDbType.VarBinary)).Value = tmpB.ToArray();
                    }
                    if (obj.qxC != null)
                    {
                        List<byte> tmpC = new List<byte>();
                        for (int i = 0; i < obj.qxB.Count; i++)
                        {
                            int v = obj.qxB[i].wValue;
                            tmpC.Add((byte)v);
                            tmpC.Add((byte)(v >> 8));
                        }
                        InsertCommand.Parameters.Add(new MySqlParameter("?qxC", MySqlDbType.VarBinary)).Value = tmpC.ToArray();
                    }
                    if (obj.glqx != null)
                    {
                        List<byte> tmpG = new List<byte>();
                        for (int i = 0; i < obj.glqx.Count; i++)
                        {
                            int v = obj.glqx[i].wValue;
                            tmpG.Add((byte)v);
                            tmpG.Add((byte)(v >> 8));
                        }
                        InsertCommand.Parameters.Add(new MySqlParameter("?gl", MySqlDbType.VarBinary)).Value = tmpG.ToArray();
                    }

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }

        /// <summary>
        /// 重载写道岔参考，摩擦曲线，只有一条曲线和功率曲线时调用
        /// </summary>
        /// <param name="f"></param>无用，用于区分重载函数
        /// <param name="qxtype"></param>
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="zh_order"></param>
        /// <param name="dotNumber"></param>
        /// <param name="qxA"></param>
        /// <param name="glqx"></param>
        /// <returns></returns>
        public bool InsertDcCkMcQxTable(bool f, byte qxtype, string TableName, int u_time, AnalogCodeType codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA, byte[] glqx)
        {
            bool tmpFlag = false;
            if (TableName == "") return tmpFlag;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                        
                
                if (con != null)
                {
                    StringBuilder DeleteStatement = new StringBuilder();
                    DeleteStatement.Append(string.Format("delete from {0} where dev_no={1} and zh_order={2} and type={3} and codetype = {4}", TableName, dev_no, zh_order, qxtype, codetype));
                    MySqlCommand delCommand = new MySqlCommand(DeleteStatement.ToString(), con);
                    delCommand.ExecuteNonQuery();

                    StringBuilder InsertStatement = new StringBuilder();

                    InsertStatement.Append(string.Format("insert into {0}(u_time,type,codetype,dev_no,zh_order,dotNumber,qxA,gl)", TableName));

                    InsertStatement.Append("values(?u_time,?type,?codetype,?dev_no,?zh_order,?dotNumber,?qxA,?gl)");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);

                    InsertCommand.Parameters.Add(new MySqlParameter("?u_time", MySqlDbType.UInt32)).Value = u_time;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.UInt16)).Value = dev_no;
                    InsertCommand.Parameters.Add(new MySqlParameter("?codetype", MySqlDbType.UInt16)).Value = codetype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?type", MySqlDbType.UInt16)).Value = qxtype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?zh_order", MySqlDbType.UByte)).Value = zh_order;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNumber", MySqlDbType.UInt16)).Value = dotNumber;
                    InsertCommand.Parameters.Add(new MySqlParameter("?qxA", MySqlDbType.VarBinary)).Value = qxA.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?gl", MySqlDbType.VarBinary)).Value = glqx.ToArray();

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }

        private void AddDataToDcCkMcValue(byte qxtype, int u_time, int codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA = null, byte[] qxB = null, byte[] qxC = null, byte[] glqx = null)
        {
            ObjDcdlType tmp = new ObjDcdlType();
            tmp.devNo = dev_no;
            tmp.u_time = u_time;
            tmp.zh_order = zh_order;
            tmp.dotNumber = dotNumber;
            string AnalogName =  "道岔动作电流曲线";
            if (qxA != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {                    
                    int TmpValue = qxA[m] + (qxA[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.qxA.Add(v);
                }
            }
            if (qxB != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {                    
                    int TmpValue = qxB[m] + (qxB[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.qxB.Add(v);
                }
            }
            if (qxC != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {
                    int TmpValue = qxC[m] + (qxC[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.qxC.Add(v);
                }
            }
            if (glqx != null)
            {
                int m = 0;
                for (int i = 0; i < dotNumber; i++)
                {
                    int TmpValue = glqx[m] + (glqx[m + 1] << 8);
                    m += 2;
                    ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                    ObjRCurValue v = new ObjRCurValue();
                    v.wValue = (short)TmpValue;
                    v.tValue = t;
                    tmp.glqx.Add(v);
                }
            }

            if (qxtype == 1)    //参考
            {
                DcdzCKqxValueList.Add(tmp);
            }
            else if (qxtype == 2)   //摩擦
            {
                DcdzMcqxValueList.Add(tmp);
            }
        }

        private void AddDataToDcCkMcValue(bool f, byte qxtype, int u_time, int codetype, Int16 dev_no, byte zh_order, Int16 dotNumber, byte[] qxA, byte[] glqx)
        {
            ObjDcdlType tmp = new ObjDcdlType();
            tmp.devNo = dev_no;
            tmp.u_time = u_time;
            tmp.zh_order = zh_order;
            tmp.dotNumber = dotNumber;
            string AnalogName = "道岔动作电流曲线";
            int m = 0;
            for (int i = 0; i < dotNumber; i++)
            {
                int TmpValue = qxA[m] + (qxA[m + 1] << 8);
                m += 2;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                ObjRCurValue v = new ObjRCurValue();
                v.wValue = (short)TmpValue;
                v.tValue = t;
                tmp.qxA.Add(v);
            }
            m = 0;
            for (int i = 0; i < dotNumber; i++)
            {
                int TmpValue = glqx[m] + (glqx[m + 1] << 8);
                m += 2;
                ObjValue t = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)TmpValue);
                ObjRCurValue v = new ObjRCurValue();
                v.wValue = (short)TmpValue;
                v.tValue = t;
                tmp.glqx.Add(v);
            }

            if (qxtype == 1)    //参考
            {
                DcdzCKqxValueList.Add(tmp);
            }
            else if (qxtype == 2)   //摩擦
            {
                DcdzMcqxValueList.Add(tmp);
            }
        }

        /// <summary>
        /// 读参考曲线或者摩擦曲线，一次读出某设备所有的参考或者摩擦曲线
        /// </summary>
        /// <param name="qxtype"></param>1为去参考曲线，2为取摩擦曲线
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="qxA"></param>
        /// <param name="qxB"></param>
        /// <param name="qxC"></param>
        /// <param name="glqx"></param>
        /// <returns></returns>
        private void ThreadReadDcCkMcQX(object o)
        {
            DcdlqxThreadStruct obj = (DcdlqxThreadStruct)o;

            byte qxtype = (byte)obj.qxtype;
            int codetype = obj.codetype;
            string TableName = obj.TableName;
            short dev_no = (Int16)obj.dev_no;
            bool qxA = obj.qxA;
            bool qxB = obj.qxB;
            bool qxC = obj.qxC;
            bool glqx = obj.glqx;

            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    if (qxtype == 1) ckqxErrorFlag = 1;
                    else mcqxErrorFlag = 1;
                }
                        
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append("select u_time,zh_order,dotNumber");
                    if (qxA == true) SelectStatement.Append(",qxA");
                    if (qxB == true) SelectStatement.Append(",qxB");
                    if (qxC == true) SelectStatement.Append(",qxC");
                    if (glqx == true) SelectStatement.Append(",gl");

                    SelectStatement.Append(string.Format(" from {0} where  dev_no = {1} and type = {2}", TableName, dev_no, qxtype));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            int u_time = read.GetInt32(read.GetOrdinal("u_time"));
                            byte zh_order = read.GetByte(read.GetOrdinal("zh_order"));
                            Int16 dotNumber = read.GetInt16(read.GetOrdinal("dotNumber"));
                            byte[] tqxa = new byte[2000];
                            byte[] tqxb = new byte[2000];
                            byte[] tqxc = new byte[2000];
                            byte[] tglqx = new byte[2000];
                            if (qxA)
                            {
                                read.GetBytes(read.GetOrdinal("qxA"), 0, tqxa, 0, dotNumber * 2);
                            }
                            if (qxB)
                            {
                                read.GetBytes(read.GetOrdinal("qxB"), 0, tqxb, 0, dotNumber * 2);
                            }
                            if (qxC)
                            {
                                read.GetBytes(read.GetOrdinal("qxC"), 0, tqxb, 0, dotNumber * 2);
                            }
                            if (glqx)
                            {
                                read.GetBytes(read.GetOrdinal("gl"), 0, tqxb, 0, dotNumber * 2);
                            }

                            if (qxA && (!qxB) && (!qxC) && (!glqx)) //只有一条曲线
                            {
                                AddDataToDcCkMcValue(qxtype, u_time, codetype, dev_no, zh_order, dotNumber, tqxa);
                            }
                            else if (qxA && (!qxB) && (!qxC) && glqx)//有一条曲线和功率曲线
                            {
                                AddDataToDcCkMcValue(true, qxtype, u_time, codetype, dev_no, zh_order, dotNumber, tqxa, tglqx);
                            }
                            else if (qxA && qxB && qxC && (!glqx))  //有三条曲线
                            {
                                AddDataToDcCkMcValue(qxtype, u_time, codetype, dev_no, zh_order, dotNumber, tqxa, tqxb, tqxc);
                            }
                            else if (qxA && qxB && qxC && glqx)     //有四条曲线
                            {
                                AddDataToDcCkMcValue(qxtype, u_time, codetype, dev_no, zh_order, dotNumber, tqxa, tqxb, tqxc, tglqx);
                            }
                        }
                        read.Close();
                        if (qxtype == 1) Ready_DcdzCKValue = true;
                        else if (qxtype == 2) Ready_DcdzMcValue = true;
                    }
                    catch (MySqlException e)
                    {
                        if (qxtype == 1) ckqxErrorFlag = 2;
                        else mcqxErrorFlag = 2;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        if (qxtype == 1) ckqxErrorFlag = 3;
                        else mcqxErrorFlag = 3;
                    }
                }
                else
                {
                    if (qxtype == 1) ckqxErrorFlag = 6;
                    else mcqxErrorFlag = 6;
                }
            }
            else
            {
                if (qxtype == 1) ckqxErrorFlag = 7;
                else mcqxErrorFlag = 7;
            }
        }
        #endregion

        #endregion
    }
}
